package ldh.im.fxbase.service;

import ldh.im.ClientChannelService;
import ldh.im.dto.base.Dto;
import ldh.im.exception.ImServiceException;
import ldh.im.fxbase.util.ThreadPoolUtil;

import java.sql.SQLException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;

public class ClientChannelServiceFactory {

    private static ClientChannelServiceFactory instance = null;
    private ClientChannelService clientChannelService = null;

    private ConcurrentHashMap<Class, MessageReceiveHandle> messageReceiveHandleConcurrentHashMap;

    public static ClientChannelServiceFactory getInstance() {
        if (instance == null) {
            synchronized (ClientChannelService.class) {
                if (instance == null) {
                    instance = new ClientChannelServiceFactory();
                }
            }
        }
        return instance;
    }

    private ClientChannelServiceFactory() {
        messageReceiveHandleConcurrentHashMap = new ConcurrentHashMap<>();
        Consumer<Dto> responseConsumer = (to)->{
            ThreadPoolUtil.submit(()->{
                try {
                    Dto obj = handleResponse(to);
                    if (obj != null) {
                        writeMessage(obj);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

            });
        };
        clientChannelService = new ClientChannelService("localhost", 9090, responseConsumer);
    }

    private <T extends Dto> T handleResponse(Dto dto) throws SQLException {
        MessageReceiveHandle messageReceiveHandle = messageReceiveHandleConcurrentHashMap.get(dto.getClass());
        if (messageReceiveHandle == null) {
            throw new RuntimeException("没有对应的消息处理器:" + dto.getClass());
        }
        return (T) messageReceiveHandle.handleMessage(dto);
    }

    public void writeMessage(Dto dto, Consumer<Dto> consumer) throws InterruptedException, ImServiceException {
        clientChannelService.write(dto, consumer);
    }

    public void writeMessage(Dto dto) throws ImServiceException, InterruptedException {
        clientChannelService.writeAsync(dto);
    }
}
